package milkyway.hightech.timer;

/**
 *
 * @author michael
 */
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;

import java.net.URL;

import java.text.DateFormat;

import java.util.Calendar;
import java.util.Date;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Clock extends JFrame
{
    private final int CLOCKSIZE;

    /**
     * the calendar object to get the time
     */
    private Calendar calendar;

    /**
     * represents the centerposition of the panel
     */
    private Point centerPanel;

    /**
     * shape of the clock
     */
    private Image image;
    private JPanel panel;

    /**
     *
     * @param calendar
     */
    public Clock(Calendar calendar)
    {
        this.setTitle("Clock");
        this.setAlwaysOnTop(true);
        this.setResizable(false);
        
        Class clazz = TimeEmitter.class;
        
        URL iconUrl = clazz.getResource("icon.png");
        ImageIcon icon = new ImageIcon(iconUrl);
        this.setIconImage(icon.getImage());
        
        URL imageUrl = clazz.getResource("clock.png");
        ImageIcon clock = new ImageIcon(imageUrl);
        this.image = clock.getImage();
        
        this.CLOCKSIZE = image.getHeight(null);
        this.panel = new ClockDisplay();
        this.panel.setDoubleBuffered(true);
        this.add("Center", panel);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(CLOCKSIZE + 14, CLOCKSIZE + 38);
        this.setVisible(true);
        this.calendar = calendar;
        
        Point point = new Point(panel.getWidth() / 2, panel.getHeight() / 2);
        this.centerPanel = point;
    }

    public void paintComponent()
    {
        panel.repaint();
    }

    /**
     * inner class to display the clock
     */
    private class ClockDisplay extends JPanel
    {
        /**
         *
         * @param g
         */
        @Override
        public void paintComponent(Graphics g)
        {
            if (calendar == null)
            {
                return;
            }

            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g;

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            
            Date date = calendar.getTime();
            
            clearPanel(g2d);
            drawFonts(g2d, date);
            drawHours(g2d, date);
            drawMinutes(g2d, date);
            drawSeconds(g2d, date);
            g2d.setColor(Color.black);
            g2d.fillArc(centerPanel.x - 5, centerPanel.y - 5, 10, 10, 0, 360);
            g2d.drawImage(image, 5, 5, null);
        }

        /**
         * fill panel with one color
         * @param g2d
         */
        private void clearPanel(Graphics2D g2d)
        {
            g2d.setColor(Color.white);
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }

        /**
         * draws the clocknumbers
         * @param g2d
         * @param date
         */
        private void drawFonts(Graphics2D g2d, Date date)
        {
            int x = 0, y = 0;

            g2d.setColor(Color.BLACK);
            g2d.setFont(new Font(null, Font.BOLD, 13));

            DateFormat timeFormatter = DateFormat.getTimeInstance();

            g2d.drawString(timeFormatter.format(date.getTime()),
                centerPanel.x - 20, centerPanel.y + 20);

            DateFormat dateFormatter = DateFormat.getDateInstance();

            g2d.drawString(dateFormatter.format(date.getTime()),
                centerPanel.x - 25, centerPanel.y + 35);

            for (int i = 1; i <= 12; i++)
            {
                if ((4 < i) && (i < 8))
                {
                    x = (int)(Math.cos(Math.toRadians(i * 30 - 90))
                        * CLOCKSIZE / 3 + centerPanel.x) - 4;
                    
                    y = (int)(Math.sin(Math.toRadians(i * 30 - 90))
                        * CLOCKSIZE / 3 + centerPanel.y) + 8;
                }
                
                else
                {
                    x = (int)(Math.cos(Math.toRadians(i * 30 - 90))
                        * CLOCKSIZE / 3 + centerPanel.x) - 4;
                    
                    y = (int)(Math.sin(Math.toRadians(i * 30 - 90))
                        * CLOCKSIZE / 3 + centerPanel.y) + 4;
                }

                g2d.drawString(Integer.toString(i), x, y);
            }
        }

        /**
         * draws a line to represent hours
         * @param g2d
         * @param date
         */
        private void drawHours(Graphics2D g2d, Date date)
        {
            g2d.setColor(Color.black);

            int hoursX = (int)(Math.cos(Math.toRadians(date.getHours()
                * 30 - 90)) * CLOCKSIZE / 3.8 + centerPanel.x);
            
            int hoursY = (int)(Math.sin(Math.toRadians(date.getHours()
                * 30 - 90)) * CLOCKSIZE / 3.8 + centerPanel.y);

            g2d.drawLine(centerPanel.x, centerPanel.y, hoursX, hoursY);
        }

        /**
         * draws a line to represent minutes
         * @param g2d
         * @param date
         */
        private void drawMinutes(Graphics2D g2d, Date date)
        {
            g2d.setColor(Color.black);

            int minutesX = (int)(Math.cos(Math.toRadians((date.getHours()
                * 6 - 90) + 6 * date.getSeconds() / 60))
                * CLOCKSIZE / 2.8 + centerPanel.x);
            
            int minutesY = (int)(Math.sin(Math.toRadians((date.getHours()
                * 6 - 90) + 6 * date.getMinutes() / 60))
                * CLOCKSIZE / 2.8 + centerPanel.y);

            g2d.drawLine(centerPanel.x, centerPanel.y, minutesX, minutesY);
        }

        /**
         * draws a line to represent seconds
         * @param g2d
         * @param date
         */
        private void drawSeconds(Graphics2D g2d, Date date)
        {
            g2d.setColor(Color.red);

            int secondsX = (int)(Math.cos(Math.toRadians(date.getSeconds()
                * 6 - 90)) * CLOCKSIZE / 2.8 + centerPanel.x);
            
            int secondsY = (int)(Math.sin(Math.toRadians(date.getSeconds()
                * 6 - 90)) * CLOCKSIZE / 2.8 + centerPanel.y);

            g2d.drawLine(centerPanel.x, centerPanel.y, secondsX, secondsY);
        }
    }
}
